package dht.message;
import java.util.HashMap;
import java.util.Map;

/**
 * Enum OpCodes to differentiate between Message types
 * 
 *	The value associated with these enums (basically the ordinal, but
 *	to make it more explicit) is what will be written in the packet
 *  header - it is 2 bytes (a short)
 *	
 * @author Steve
 *
 */
public enum OpCode {
	
	Heartbeat(1),
	PrepareRequest(2), 
	PrepareResponse(3), 
	AcceptRequest(4), 
	AcceptResponse(5),
	Query(6),
	// this is here incase there is a problem
	// trying to convert int -> OpCode -
	// so we don't have to check for null, just
	// return this
	Unknown(7);
	
	// cash the short - to - OpCode mapping 
	// so you can go from int to OpCode easily
	private static final Map<Short, OpCode> map = new HashMap<>();
	static {
		for (OpCode oc : OpCode.values())
			map.put(new Short(oc.value()), oc);
	}
	
	private final short code;
	private OpCode(int code)
	{
		this((short)code);
	}
	private OpCode(short code)
	{
		this.code = code;
	}
	
	/**
	 * @return the short value associated with this OpCode
	 */
	public short value()
	{
		return code;
	}
	
	/**
	 * A convenience method. It returns OpCode.convert((short)code);
	 */
	public static OpCode convert(int code)
	{
		return convert((short)code);
	}

	/**
	 * @param code a short value corresponding to an OpCode
	 * @return the OpCode corresponding to the specified short, or
	 *          OpCode.Unknown if the short does not map to an OpCode
	 */
	public static OpCode convert(short code)
	{
		OpCode oc = map.get(code);
		if (oc == null) {
			return OpCode.Unknown;
		}
		return oc;
	}
	
}
